﻿
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Text.RegularExpressions;

namespace Test30.Core
{
    public class IndentationTree
    {
        public int Indent => _indent;

        public string Text { get; }

        public ReadOnlyCollection<IndentationTree> Children => new ReadOnlyCollection<IndentationTree>(_children);

        public static IndentationTree Parse(IEnumerable<string> lines)
        {
            if (lines == null) throw new ArgumentNullException($"lines");

            Stack<IndentationTree> stack = new Stack<IndentationTree>();

            // start with a blank root node
            IndentationTree root = new IndentationTree(-1, String.Empty);
            stack.Push(root);

            foreach (string line in lines)
            {
                Match match = SIndentRegex.Match(line);

                // create the new branch
                int indent = match.Groups["indent"].Value.Length;
                string text = match.Groups["text"].Value;

                IndentationTree tree = new IndentationTree(indent, text);

                // insert it in the tree
                if (indent > stack.Peek().Indent)
                {
                    // indented more, so push a new tree
                    stack.Peek()._children.Add(tree);
                    stack.Push(tree);
                }
                else
                {
                    // indented less or equal, so pop until we reach the right level
                    while (stack.Peek().Indent >= indent)
                    {
                        stack.Pop();
                    }

                    stack.Peek()._children.Add(tree);
                    stack.Push(tree);
                }
            }

            root.NormalizeIndentation(-1);

            return root;
        }

        private void NormalizeIndentation(int currentIndent)
        {
            _indent = currentIndent;

            foreach (IndentationTree child in _children)
            {
                child.NormalizeIndentation(currentIndent + 1);
            }
        }
        private IndentationTree(int indent, string text)
        {
            _indent = indent;
            Text = text;
        }
        private static readonly Regex SIndentRegex = new Regex(
            @"^(?<indent>\s*) # leading whitespace
               (?<text>.*)$   # everything else",
            RegexOptions.Compiled | RegexOptions.ExplicitCapture | RegexOptions.IgnorePatternWhitespace);

        private int _indent;

        private readonly List<IndentationTree> _children = new List<IndentationTree>();
    }

}
